(function defineWeekUnitTable(weekUnitTable) {

    if (typeof module !== 'undefined' && typeof exports === 'object' && define.cmd) {
        module.exports = weekUnitTable;
    } else if (typeof define === 'function' && define.amd) {
        define(function() {
            return weekUnitTable;
        });
    } else {
        window.WeekUnitTable = weekUnitTable;
    }

})((function($) {

    var weekUnitTable = function(opt) {
        this.params = {
            uuid: getUuid(),
            container: '', //容器
            weeks: false,
            units: false,
            loadWeeksUrl: false,
            loadUnitsUrl: false,
            convertWeeksFunc: false, // 与loadWeeksUrl配合使用，用于通过ajax获取数据后，对数据进行转换的函数
            convertUnitsFunc: false, // 与loadUnitsUrl配合使用，用于通过ajax获取数据后，对数据进行转换的函数
            choicedHtml: '<div class="wut_choiced"><div>已选</div></div>',
            readOnly: false
        };

        this.choicedDatas = [];
        this.isMouseDown = false;

        this.init(opt);
    };

    weekUnitTable.prototype = {

        /**
         * 初始化
         * @param  {[object]} opt [构建对象传递的参数]
         */
        init: function(opt) {
            copyPropertyVal(opt, this.params);
        },

        /**
         * 渲染
         */
        render: function() {
            var _weeks = this.getWeeks();
            var _units = this.getUnits();

            var _html = '<div id="div_' + this.params.uuid + '" class="wut_container">';
            _html += '      <table class="wut_table" onselectstart="return false">';
            _html += '          <tr>';
            _html += '              <td data-role="weekOrUnit">全选/取消全选</td>';
            for (var i = 0; i < _weeks.length; i++) {
                var _w = _weeks[i];
                _html += '          <td class="wut_fontsize13" data-role="weekOrUnit" data-week="' + _w.code + '" title="全选/取消选择“' + _w.name + '”的内容">' + _w.name + '</td>';
            }
            _html += '           </tr>';

            for (var i = 0; i < _units.length; i++) {
                var _u = _units[i];
                _html += '      <tr>';
                _html += '              <td class="wut_fontsize13" data-role="weekOrUnit" data-unit="' + _u.code + '" title="全选/取消选择“' + _u.name + '”的内容">' + _u.name + '</td>';
                for (var j = 0; j < _weeks.length; j++) {
                    _html += '          <td data-role="item" data-week="' + _weeks[j].code + '" data-unit="' + _u.code + '"></td>';
                }
                _html += '      </tr>';
            }

            _html += '      </table>';
            _html += '  </div>';

            $(this.params.container).html(_html);

            this.setReadOnly();
            this.bindEvent();
        },

        setReadOnly: function(readOnly) {
            if (readOnly != null)
                this.params.readOnly = readOnly;

            if (this.params.readOnly) {
                $('.wut_table').find('td').addClass("wut_notallowed");
            } else {
                $('.wut_table').find('td').removeClass("wut_notallowed");
            }
        },

        bindEvent: function() {
            var _this = this;

            /**
             * 鼠标点击元素产生的事件
             */
            $('#div_' + _this.params.uuid).find('td[data-role="item"]').mousedown(function(e) {
                if (_this.params.readOnly) return;

                var jdom = $(this);
                jdom.toggleClass("wut_selecting");
                _this.isMouseDown = true;

            }).mousemove(function(e) {
                if (_this.params.readOnly) return;
                if (!_this.isMouseDown) return;
                var jobj = $(this);

                jobj.toggleClass("wut_selecting", true);
                jobj.html('');
            }).mouseup(function(e) {
                if (_this.params.readOnly) return;
                _this.isMouseDown = false;

                // 根据样式将当前选择的元素统一放到choicedDatas中
                $('#div_' + _this.params.uuid).find('.wut_selecting').each(function() {
                    var jobj = $(this);
                    var curChoiced = {
                        week: jobj.attr("data-week"),
                        unit: jobj.attr("data-unit")
                    };
                    var index = contains(_this.choicedDatas, curChoiced, ['week', 'unit']);
                    if (index === -1) {
                        _this.choicedDatas.push(curChoiced);
                        _this.setItemContent(jobj);
                    } else {
                        _this.choicedDatas.splice(index, 1);
                        _this.setItemContent(jobj, '');
                    }
                });

                // 清除当前选中的样式
                $('#div_' + _this.params.uuid).find('td[data-role="item"]').toggleClass("wut_selecting", false);
            });

            /**
             * 点击星期节次标题产生的事件
             */
            $('#div_' + _this.params.uuid).find('td[data-role="weekOrUnit"]').click(function() {
                if (_this.params.readOnly) return;
                var week = $(this).attr("data-week") || 'null';
                var unit = $(this).attr("data-unit") || 'null';

                //判断当前星期是否有存在的没有被选中的项，如果有，则默认都选中，否则默认都取消选中
                var hasNoChoiced = false;
                $('#div_' + _this.params.uuid).find('td[data-role="item"]').each(function() {
                    var jobj = $(this);
                    var curChoiced = {
                        week: jobj.attr('data-week'),
                        unit: jobj.attr('data-unit')
                    };

                    if ((curChoiced.week == week || curChoiced.unit == unit || (week === unit && week === 'null')) && contains(_this.choicedDatas, curChoiced, ['week', 'unit']) == -1) {
                        hasNoChoiced = true;
                        return false;
                    }
                });

                $('#div_' + _this.params.uuid).find('td[data-role="item"]').each(function() {
                    var jobj = $(this);
                    var curChoiced = {
                        week: jobj.attr('data-week'),
                        unit: jobj.attr('data-unit')
                    };

                    if (hasNoChoiced) {
                        if ((curChoiced.week == week || curChoiced.unit == unit || (week === unit && week === 'null')) && contains(_this.choicedDatas, curChoiced, ['week', 'unit']) == -1) {
                            _this.choicedDatas.push(curChoiced);
                            _this.setItemContent(jobj);
                        }
                    } else {
                        var index = contains(_this.choicedDatas, curChoiced, ['week', 'unit']);
                        if ((curChoiced.week == week || curChoiced.unit == unit || (week === unit && week === 'null')) && index != -1) {
                            _this.choicedDatas.splice(index, 1);
                            _this.setItemContent(jobj, '');
                        }
                    }
                });

            });
        },

        setItemContent: function(jobj, content) {
            jobj.html(content != null ? content : this.params.choicedHtml);
        },

        getWeeks: function() {
            // 如果参数带有weeks，则直接使用参数的weeks
            if (this.params.weeks)
                return this.params.weeks;
            // 如果参数中写了获取weeks的URL，则使用ajax获取相应的weeks
            if (this.params.loadWeeksUrl)
                return this.getAjaxWeeks();
            // 获取默认提供的weeks
            return this.getDefaultWeeks();
        },

        /**
         * 获取默认的星期
         */
        getDefaultWeeks: function() {
            return [{
                code: '1',
                name: '星期一'
            }, {
                code: '2',
                name: '星期二'
            }, {
                code: '3',
                name: '星期三'
            }, {
                code: '4',
                name: '星期四'
            }, {
                code: '5',
                name: '星期五'
            }, {
                code: '6',
                name: '星期六'
            }, {
                code: '7',
                name: '星期日'
            }];
        },

        /**
         * 通过ajax获取星期
         */
        getAjaxWeeks: function() {
            var _this = this;
            var _weeks = [];
            $.ajax({
                url: this.params.loadWeeksUrl,
                cache: false,
                dataType: "json",
                type: "get",
                async: false,
                success: function(data) {
                    if (_this.params.convertWeeksFunc) {
                        _weeks = _this.params.convertWeeksFunc(data);
                    } else {
                        _weeks = data;
                    }
                }
            });
            return _weeks;
        },

        getUnits: function() {
            // 如果参数带有units，则直接使用参数的units
            if (this.params.units)
                return this.params.units;
            // 如果参数中写了获取units的URL，则使用ajax获取相应的units
            if (this.params.loadUnitsUrl)
                return this.getAjaxUnits();
            // 获取默认提供的weeks
            return this.getDefaultUnits();
        },

        /**
         * 通过ajax获取节次
         */
        getAjaxUnits: function() {
            var _this = this;
            var _units = [];
            $.ajax({
                url: this.params.loadUnitsUrl,
                cache: false,
                dataType: "json",
                type: "get",
                async: false,
                success: function(data) {
                    if (_this.params.convertUnitsFunc) {
                        _units = _this.params.convertUnitsFunc(data);
                    } else {
                        _units = data;
                    }
                }
            });
            return _units;
        },

        /**
         * 获取默认的节次
         */
        getDefaultUnits: function() {
            return [{
                code: '1',
                name: '第一节'
            }, {
                code: '2',
                name: '第二节'
            }, {
                code: '3',
                name: '第三节'
            }, {
                code: '4',
                name: '第四节'
            }, {
                code: '5',
                name: '第五节'
            }, {
                code: '6',
                name: '第六节'
            }, {
                code: '7',
                name: '第七节'
            }, {
                code: '8',
                name: '第八节'
            }, {
                code: '9',
                name: '第九节'
            }, {
                code: '10',
                name: '第十节'
            }, {
                code: '11',
                name: '第十一节'
            }, {
                code: '12',
                name: '第十二节'
            }];
        },

        setResult: function(data) {
            var _this = this;
            this.choicedDatas = data;

            // 清除页面已选择的元素
            $('#div_' + _this.params.uuid).find('td[data-role="item"]').html('');
            // 重新渲染指定的内容
            $('#div_' + _this.params.uuid).find('td[data-role="item"]').each(function() {
                var jobj = $(this);
                for (var i = 0; i < _this.choicedDatas.length; i++) {
                    if (_this.choicedDatas[i].unit == jobj.attr('data-unit') && _this.choicedDatas[i].week == jobj.attr('data-week')) {
                        _this.setItemContent(jobj);
                        break;
                    }
                }
            });
        },

        /**
         * 获取结果
         */
        getResult: function() {
            return this.choicedDatas;
        }
    }

    /**
     * 获取已选择的周次的下标，下标从1开始
     * @param binaryStr 二进制串
     */
    function getWeekIndexs(binaryStr) {
        var indexArrs = [];
        for (i = 0; i < binaryStr.length; i++) {
            var bs = binaryStr.charAt(i);
            if (bs === "1")
                indexArrs.push(i + 1);
        }
        return indexArrs;
    }

    /**
     * 数组是否包含，如果包含返回下标，不包含返回-1
     * @param arrs
     * @param obj
     */
    function contains(arrs, obj, props) {
        for (var i = 0; i < arrs.length; i++) {
            var arr = arrs[i];
            var isSame = true;
            for (var j = 0; j < props.length; j++) {
                var prop = props[j];
                if (arr[prop] == null || obj[prop] == null || arr[prop] != obj[prop]) {
                    isSame = false;
                    break;
                }
            }
            if (isSame) return i;
        }
        return -1;
    }

    /**
     * 参数复制
     * @param from
     * @param to
     */
    function copyPropertyVal(from, to) {
        for (var f in from) {
            for (var t in to) {
                if (f == t && from[f] != null) {
                    to[t] = from[f];
                    break;
                }
            }
        }
    }

    /**
     * 获取uuid
     * @returns {string}
     */
    function getUuid() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
        //s[8] = s[13] = s[18] = s[23] = "-";
        s[8] = s[13] = s[18] = s[23] = "";

        var uuid = s.join("");
        return uuid;
    }

    return weekUnitTable;

}(jQuery)));
